package structural.proxy;


/**
 * 代理模式
 * 静态代理和动态代理
 */


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 静态代理
 */
interface Product{

    public void action();
}

class Car implements Product{
    private String name;

    public Car() {
    }

    public Car(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void action() {
        System.out.println("action ----- >  Car:"+this.name);
    }
}

class Food implements Product{
    private String name;

    public Food() {
    }

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void action() {
        System.out.println("action ----- >  Food:"+this.name);
    }
}

class ProxyProduct implements Product{

    private Product product;

    public ProxyProduct(Product product) {
        this.product = product;
    }

    public ProxyProduct(String type,String name) {
        if ("car".equalsIgnoreCase(type)){
            this.product = new Car(name);
        }else if ("Food".equalsIgnoreCase(type)){
            this.product = new Food(name);
        }else {
            throw new RuntimeException("未知产品类型");
        }
    }

    @Override
    public void action() {
        System.out.println("action ---Before--- > ProxyProduct:");
        product.action();
        System.out.println("action ---After--- > ProxyProduct:");
    }
}

//class Test{
//    public static void main(String[] args) {
//        Product product = new ProxyProduct("car","大众");
//        product.action();
//
//        Product product02 = new ProxyProduct("food","薯片");
//        product02.action();
//    }
//}


/**
 * 动态代理
 */

interface Animal{
    public int action();

    public int add(int num);
}

class Bee implements Animal{

    private static int count = 0;

    @Override
    public int action() {
        System.out.println("addBeeCount -----> Bee");
        count++;
        return count;
    }

    @Override
    public int add(int num) {
        System.out.println("addBeeCount -----> Bee");
        count += num;
        return count;
    }
}


class ProxyAnimal implements InvocationHandler{

    private Object object;

    public ProxyAnimal(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("action ---Before--- > ProxyAnimal:");
        Object result = method.invoke(object, args);
        System.out.println("action ---Before--- > ProxyAnimal:");
        return result;
    }
}


class Test{
    public static void main(String[] args) {
        Animal animal = new Bee();
        ProxyAnimal proxyAnimal = new ProxyAnimal(animal);
        Animal newProxyInstance = (Animal) Proxy.newProxyInstance(Animal.class.getClassLoader(), new Class[]{Animal.class}, proxyAnimal);
        System.out.println(newProxyInstance.action());
        System.out.println(newProxyInstance.add(15));
    }
}


